#include "prisoner.h"

sfSprite *selection;
int selectionX, selectionY;


/*
 * ed_Init
 *
 * Fonction d'initialisation de l'éditeur
 *
 */
int ed_Init() {
	int x,y;

	// coloration de la case de sélection
	sfColor couleurSelection = {255, 0, 0, 128};

	/*
	 * Initialisation du tableau des décorations et entités
	 */
	for (x = 0; x< NOMBRE_CASES_LONGUEUR; x++)
	{
		for (y = 0; y< NOMBRE_CASES_LARGEUR; y++)
		{
			grille[x][y] = NULL;
			entites[x][y] = NULL;
		}
	}

	// chargement du fichier de niveau
	ed_Load();

	// création du sprite de sélection
	selection = sfSprite_Create();
	sfSprite_Resize(selection, LONGUEUR_CASE, LARGEUR_CASE);
	sfSprite_SetColor(selection, couleurSelection);

	// positionnement du curseur de sélection en haut à gauche
	selectionX = 0;
	selectionY = 0;
	return 1;
}

/*
 * ed_Load()
 *
 * Chargement du fichier de niveau dans l'éditeur
 */
int ed_Load()
{
	char Case;
	int i, x, y, nombre;
	char direction;

	// ouverture du fichier niveau en mode lecture binaire
	FILE* f = fopen("niveau.txt", "rb");

	// si il est impossible de l'ouvrir, on quitte la fonction
	if (f == NULL)
		return 0;

	// le premier entier est le nombre de cases décoration enregistrées
	fread(&nombre, sizeof(int), 1, f);

	// pour chaque case décoration
	for (i = 0; i < nombre; i++)
	{
		// extraction des informations de la case
		fread(&Case, sizeof(char), 1, f);
		fread(&x, sizeof(int), 1, f);
		fread(&y, sizeof(int), 1, f);

		// création de la case de décoration
		grille[x][y] = sfSprite_Create();

		if(Case == CASE_SOL)
			sfSprite_SetImage(grille[x][y], imgSol);
		else if(Case == CASE_MUR)
			sfSprite_SetImage(grille[x][y], imgMur);

		sfSprite_SetPosition(grille[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
	}

	fread(&nombre, sizeof(int), 1, f);

	for (i = 0; i < nombre; i++)
	{
		// extraction des informations de la case
		fread(&Case, sizeof(char), 1, f);
		fread(&direction, sizeof(char), 1, f);
		fread(&x, sizeof(int), 1, f);
		fread(&y, sizeof(int), 1, f);

		// création de la case de décoration
		entites[x][y] = sfSprite_Create();

		if(Case == ENTITE_DEPART)
		{
			if(direction == DIR_DROITE)
				sfSprite_SetImage(entites[x][y], imgDepart_droite);
			else if(direction == DIR_GAUCHE)
				sfSprite_SetImage(entites[x][y], imgDepart_gauche);
			else if(direction == DIR_HAUT)
				sfSprite_SetImage(entites[x][y], imgDepart_haut);
			else if(direction == DIR_BAS)
				sfSprite_SetImage(entites[x][y], imgDepart_bas);
		}
		else if (Case == ENTITE_ARRIVE)
			sfSprite_SetImage(entites[x][y], imgArrivee);
		else if (Case == ENTITE_CLE)
			sfSprite_SetImage(entites[x][y], imgCle);
		else if (Case == ENTITE_CAISSE)
					sfSprite_SetImage(entites[x][y], imgCaisse);
		else if (Case == ENTITE_PORTE_FERMEE)
			sfSprite_SetImage(entites[x][y], imgPorte_fermee);
		else if (Case == ENTITE_GARDE)
			sfSprite_SetImage(entites[x][y], imgGarde_droite[1]);
		else if (Case == ENTITE_DIRECTION_GARDE)
			sfSprite_SetImage(entites[x][y], imgDG_bas);


		sfSprite_SetPosition(entites[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
	}


	// fermeture du fichier
	fclose(f);
	return 1;
}

/*
 * ed_SetEntity(int x, int y, char type_entite)
 *
 * Paramétrage du type d'entité à la case choisie
 */
void ed_SetEntity(int x, int y, char type_entite)
{
	switch(type_entite)
	{
		case ENTITE_DEPART:
		{
			int ix, iy;

			if(!grille[x][y])
				return;

			if(sfSprite_GetImage(grille[x][y]) != imgSol)
				return;

			for(ix = 0; ix < NOMBRE_CASES_LONGUEUR; ix++)
			{
				for(iy = 0; iy < NOMBRE_CASES_LARGEUR; iy++)
				{
					if(entites[ix][iy] && entites[ix][iy] != entites[x][y] &&
							(sfSprite_GetImage(entites[ix][iy]) == imgDepart_droite ||
							 sfSprite_GetImage(entites[ix][iy]) == imgDepart_gauche ||
							 sfSprite_GetImage(entites[ix][iy]) == imgDepart_haut ||
							 sfSprite_GetImage(entites[ix][iy]) == imgDepart_bas))
					{
						sfSprite_Destroy(entites[ix][iy]);
						entites[ix][iy] = NULL;
					}
				}
			}

			if(entites[x][y] == NULL)
			{
				entites[x][y] = sfSprite_Create();
				sfSprite_SetImage(entites[x][y], imgDepart_droite);
				sfSprite_SetPosition(entites[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
			}
			else if(sfSprite_GetImage(entites[x][y]) == imgDepart_droite)
				sfSprite_SetImage(entites[x][y], imgDepart_bas);
			else if(sfSprite_GetImage(entites[x][y]) == imgDepart_bas)
				sfSprite_SetImage(entites[x][y], imgDepart_gauche);
			else if(sfSprite_GetImage(entites[x][y]) == imgDepart_gauche)
				sfSprite_SetImage(entites[x][y], imgDepart_haut);
			else if(sfSprite_GetImage(entites[x][y]) == imgDepart_haut)
				sfSprite_SetImage(entites[x][y], imgDepart_droite);
			else
				sfSprite_SetImage(entites[x][y], imgDepart_droite);

			break;
		}
		case ENTITE_ARRIVE :
		{
			int ix, iy;

			if(!grille[x][y])
				return;
			if(sfSprite_GetImage(grille[x][y]) != imgSol)
				return;

			for(ix = 0; ix < NOMBRE_CASES_LONGUEUR; ix++)
			{
				for(iy = 0; iy < NOMBRE_CASES_LARGEUR; iy++)
				{
					if(entites[ix][iy] && entites[ix][iy] != entites[x][y] && sfSprite_GetImage(entites[ix][iy]) == imgArrivee)
					{
						sfSprite_Destroy(entites[ix][iy]);
						entites[ix][iy] = NULL;
					}
				}
			}
			if(entites[x][y] == NULL)
			{
				entites[x][y] = sfSprite_Create();
				sfSprite_SetImage(entites[x][y], imgArrivee);
				sfSprite_SetPosition(entites[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
			}
			else
				sfSprite_SetImage(entites[x][y], imgArrivee);

		break;
		case ENTITE_CLE :
			{
				int ix, iy;

				if(!grille[x][y])
					return;
				if(sfSprite_GetImage(grille[x][y]) != imgSol)
					return;

				if(entites[x][y] == NULL)
				{
					entites[x][y] = sfSprite_Create();
					sfSprite_SetImage(entites[x][y], imgCle);
					sfSprite_SetPosition(entites[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
				}
				else
					sfSprite_SetImage(entites[x][y], imgCle);

			break;
			}
		case ENTITE_CAISSE :
		{
			int ix, iy;

			if(!grille[x][y])
				return;
			if(sfSprite_GetImage(grille[x][y]) != imgSol)
				return;

			if(entites[x][y] == NULL)
			{
				entites[x][y] = sfSprite_Create();
				sfSprite_SetImage(entites[x][y], imgCaisse);
				sfSprite_SetPosition(entites[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
			}
			else
				sfSprite_SetImage(entites[x][y], imgCaisse);

		break;
		}
		case ENTITE_GARDE :
		{
			int ix, iy;

			if(!grille[x][y])
				return;
			if(sfSprite_GetImage(grille[x][y]) != imgSol)
				return;

			if(entites[x][y] == NULL)
			{
				entites[x][y] = sfSprite_Create();
				sfSprite_SetImage(entites[x][y], imgGarde_droite[1]);
				sfSprite_SetPosition(entites[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
			}
			else
				sfSprite_SetImage(entites[x][y], imgGarde_droite[1]);

		break;
		}
		case ENTITE_PORTE_FERMEE :
			{
				int ix, iy;

				if(!grille[x][y])
					return;
				if(sfSprite_GetImage(grille[x][y]) != imgMur)
					return;

				if(entites[x][y] == NULL)
				{
					entites[x][y] = sfSprite_Create();
					sfSprite_SetImage(entites[x][y], imgPorte_fermee);
					sfSprite_SetPosition(entites[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
				}
				else
					sfSprite_SetImage(entites[x][y], imgPorte_fermee);
			break;
			}
		case ENTITE_DIRECTION_GARDE:
		{
			int ix, iy;

			if(!grille[x][y])
				return;

			if(sfSprite_GetImage(grille[x][y]) != imgSol)
				return;

			if((entites[x][y+1] && ((sfSprite_GetImage(entites[x][y+1])== imgGarde_droite[1]) || (sfSprite_GetImage(entites[x][y+1])== imgDG_bas)))
					||(entites[x][y-1] && ((sfSprite_GetImage(entites[x][y-1])== imgGarde_droite[1]) || (sfSprite_GetImage(entites[x][y-1])== imgDG_bas)))
					||(entites[x+1][y] && ((sfSprite_GetImage(entites[x+1][y])== imgGarde_droite[1]) || (sfSprite_GetImage(entites[x+1][y])== imgDG_bas)))
					||(entites[x-1][y] && ((sfSprite_GetImage(entites[x-1][y])== imgGarde_droite[1]) || (sfSprite_GetImage(entites[x-1][y])== imgDG_bas))))
			{

				if(entites[x][y] == NULL)
				{
					entites[x][y] = sfSprite_Create();
					sfSprite_SetImage(entites[x][y], imgDG_bas);
					sfSprite_SetPosition(entites[x][y], x * LONGUEUR_CASE, y * LARGEUR_CASE);
				}
				else
					sfSprite_SetImage(entites[x][y], imgDG_bas);
				break;
			}
		}

		}
	}
}

/*
 * ed_Save()
 *
 * Sauvegarde du fichier de niveau
 */
int ed_Save()
{
	char Case;
	int x,y;
	int nombre = 0;

	// ouverture du fichier de niveau en écriture binaire
	FILE* f = fopen("niveau.txt", "wb");

	// le fichier est impossible à ouvrir, on quitte la procédure
	if (f == NULL)
		return 0;

	// on compte toutes les cases décoration utilisées
	for (x = 0; x < NOMBRE_CASES_LONGUEUR; x++)
	{
		for (y = 0; y < NOMBRE_CASES_LARGEUR; y++)
		{
			if(grille[x][y])
				nombre++;
		}
	}

	// le premier entier sera le nombre de cases décorations trouvées
	fwrite(&nombre, sizeof(int), 1, f);

	for (x = 0; x< NOMBRE_CASES_LONGUEUR; x++)
	{
		for (y = 0; y< NOMBRE_CASES_LARGEUR; y++)
		{
			if (!grille[x][y])
				continue;

			if(sfSprite_GetImage(grille[x][y]) == imgSol)
				Case = CASE_SOL;
			else if(sfSprite_GetImage(grille[x][y]) == imgMur)
				Case = CASE_MUR;

			// écriture des informations de la case actuelle
			fwrite(&Case, sizeof(char), 1, f);
			fwrite(&x, sizeof(int), 1, f);
			fwrite(&y, sizeof(int), 1, f);
		}
	}

	// remise à zéro du nombre de cases, puis on compte le nombre de cases
	// entité utilisées
	nombre = 0;
	for (x = 0; x < NOMBRE_CASES_LONGUEUR; x++)
	{
		for (y = 0; y < NOMBRE_CASES_LARGEUR; y++)
		{
			if(entites[x][y])
				nombre++;
		}
	}

	// écriture du nombre d'entités trouvées
	fwrite(&nombre, sizeof(int), 1, f);

	for (x = 0; x < NOMBRE_CASES_LONGUEUR; x++)
	{
		for (y = 0; y < NOMBRE_CASES_LARGEUR; y++)
		{
			char type;
			char direction;

			if (!entites[x][y])
				continue;

			if(sfSprite_GetImage(entites[x][y]) == imgDepart_droite ||
					 sfSprite_GetImage(entites[x][y]) == imgDepart_gauche ||
					 sfSprite_GetImage(entites[x][y]) == imgDepart_haut ||
					 sfSprite_GetImage(entites[x][y]) == imgDepart_bas)
			{

				type = ENTITE_DEPART;
				if (sfSprite_GetImage(entites[x][y]) == imgDepart_droite)
					direction = DIR_DROITE;
				else if (sfSprite_GetImage(entites[x][y]) == imgDepart_gauche)
					direction = DIR_GAUCHE;
				else if (sfSprite_GetImage(entites[x][y]) == imgDepart_haut)
					direction = DIR_HAUT;
				else if (sfSprite_GetImage(entites[x][y]) == imgDepart_bas)
					direction = DIR_BAS;

				// écriture des informations de la case entité

			}
			else if(sfSprite_GetImage(entites[x][y]) == imgArrivee)
			{
				type = ENTITE_ARRIVE;
				direction = DIR_DROITE;

			}
			else if(sfSprite_GetImage(entites[x][y]) == imgCle)
			{
				type = ENTITE_CLE;
				direction = DIR_DROITE;

			}
			else if(sfSprite_GetImage(entites[x][y]) == imgCaisse)
			{
				type = ENTITE_CAISSE;
				direction = DIR_DROITE;

			}
			else if(sfSprite_GetImage(entites[x][y]) == imgGarde_droite[1])
			{
				type = ENTITE_GARDE;
				direction = DIR_DROITE;

			}
			else if(sfSprite_GetImage(entites[x][y]) == imgDG_bas)
			{
				type = ENTITE_DIRECTION_GARDE;
				direction = DIR_DROITE;

			}
			else if(sfSprite_GetImage(entites[x][y]) == imgPorte_fermee)
			{
				type = ENTITE_PORTE_FERMEE;
				direction = DIR_DROITE;

			}
			fwrite(&type, sizeof(char), 1, f);
			fwrite(&direction, sizeof(char), 1, f);
			fwrite(&x, sizeof(int), 1, f);
			fwrite(&y, sizeof(int), 1, f);
		}
	}

	// fermeture du fichier
	fclose(f);
	return 0;
}

/*
 * ed_ProcessEvent
 *
 * Traitement des événements
 */
int ed_ProcessEvent(sfEvent evt) {

	if(evt.Type == sfEvtKeyPressed)
	{
	 		switch(evt.Key.Code)
	 		{
	 		case sfKeyEscape:
	 			sfRenderWindow_Close(App);
	 			break;
	 		case sfKeyRight:
	 			if (selectionX < NOMBRE_CASES_LONGUEUR -1)
	 				selectionX++;
	 			break;
	 		case sfKeyLeft:
				if (selectionX > 0)
					selectionX--;
				break;
	 		case sfKeyDown:
				if (selectionY < NOMBRE_CASES_LARGEUR -1)
					selectionY++;
				break;
	 		case sfKeyUp:
				if (selectionY > 0)
					selectionY--;
				break;
	 		case sfKeyS:
	 		{
	 			if (grille[selectionX][selectionY] == NULL)
	 			{
	 				grille[selectionX][selectionY] = sfSprite_Create();
	 				sfSprite_SetPosition(grille[selectionX][selectionY], selectionX * LONGUEUR_CASE, selectionY * LARGEUR_CASE);
	 			}
	 			if(!entites[selectionX][selectionY])
	 			sfSprite_SetImage(grille[selectionX][selectionY], imgSol);
	 			break;
	 		}
	 		case sfKeyM:

	 			if (grille[selectionX][selectionY] == NULL)
	 			{
	 				grille[selectionX][selectionY] = sfSprite_Create();
	 				sfSprite_SetPosition(grille[selectionX][selectionY], selectionX * LONGUEUR_CASE, selectionY * LARGEUR_CASE);
	 			}
	 			if(!entites[selectionX][selectionY])
	 			sfSprite_SetImage(grille[selectionX][selectionY], imgMur);
	 			break;
	 		case sfKeyF1:
	 			ed_Save();
	 			break;
	 		case sfKeyD:
	 			ed_SetEntity(selectionX, selectionY, ENTITE_DEPART);
	 			break;
	 		case sfKeyA:
	 			ed_SetEntity(selectionX, selectionY, ENTITE_ARRIVE);
	 			break;
	 		case sfKeyK:
	 			ed_SetEntity(selectionX, selectionY, ENTITE_CLE);
	 			break;
	 		case sfKeyC:
	 			ed_SetEntity(selectionX, selectionY, ENTITE_CAISSE);
	 			break;
	 		case sfKeyP:
	 			ed_SetEntity(selectionX, selectionY, ENTITE_PORTE_FERMEE);
	 			break;
	 		case sfKeyG:
	 			ed_SetEntity(selectionX, selectionY, ENTITE_DIRECTION_GARDE);
	 			break;
	 		case sfKeyH:
	 			ed_SetEntity(selectionX, selectionY, ENTITE_GARDE);
	 			break;
	 		}



	}
	return 1;
}

/*
 * ed_Loop
 * Fonction de la boucle de l'éditeur
 *
 * - Appel à la fonction de traitement des événements
 * - Appel à la fonction d'affichage (dessin des cases,...)
 *
 */
int ed_Loop() {
	int x,y;

	// affichage des cases de décoration et d'entité
	for (x = 0; x< NOMBRE_CASES_LONGUEUR; x++)
	{
		for (y = 0; y< NOMBRE_CASES_LARGEUR; y++)
		{
			if(grille[x][y] != NULL)
				sfRenderWindow_DrawSprite(App, grille[x][y]);
			if(entites[x][y] != NULL)
				sfRenderWindow_DrawSprite(App, entites[x][y]);
		}
	}

	// affichage du curseur de sélection
	sfSprite_SetPosition(selection, selectionX*LONGUEUR_CASE, selectionY*LARGEUR_CASE);
	sfRenderWindow_DrawSprite(App, selection);
	return 0;
}

/*
 * ed_Destroy
 *
 * Destruction de l'éditeur
 */
int ed_Destroy() {
	return 0;
}


